﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Web;
using DeviceFinder.Models;

namespace DeviceFinder.DAL
{
    public static class OAuthManager
    {

        public static TokenModel CreateToken(Models.OAuthModel model)
        {
            TokenModel token = null;
            //****Chưa chắc việc đồng bộ
            lock (HttpContext.Current.Application)
            {
                try
                {
                    Dictionary<string, TokenModel> dict = HttpContext.Current.Application[OAuthManager.name] as Dictionary<string, TokenModel>;
                    DateTime timeCheck = (DateTime)HttpContext.Current.Application[OAuthManager.date] + OAuthManager.updatePeriod;
                    //Tìm kiếm trong list các oAuth
                    DeviceDAL deviceDAL = new DeviceDAL();
                    UserDAL dal = new UserDAL();
                    DEVICE device = deviceDAL.GetDeviceByID(model.DeviceId);
                    if (dal.Validate(model.Email, model.Password) && device.EMAIL_USER == model.Email)//validate tài khoản
                    {
                        //              tạo token
                        DateTime date = DateTime.Now;
                        string tokenString = CalculateMD5Hash(model.DeviceId.ToString() + date.AddHours(2).ToString() + model.Password);

                        token = new TokenModel() { Token = tokenString, DeviceId = model.DeviceId, Status = TokenModel.STATUS_TOKEN.SUCCESS };
                        //              thêm vào danh sách
                        dict.Add(token.Token, token);
                        HttpContext.Current.Application[OAuthManager.name] = dict;

                        //// Kiểm tra biến thời gian
                        //if (date > timeCheck)
                        //{
                        //    HttpContext.Current.Application[OAuthManager.date] = date;
                        //    //
                        //    foreach (TokenModel t in dict)
                        //    {
                        //        if( t.
                        //    }
                        //}

                        return token;
                        // 
                    }
                    else
                    {
                        //Fail to login
                        token = new TokenModel() { Status = TokenModel.STATUS_TOKEN.FAIL };
                    }
                }
                catch (System.Exception e)
                {
                    token = new TokenModel() { Status = TokenModel.STATUS_TOKEN.FAIL, Token = e.Message };
                }
            }
            return token;
        }

        public static string CalculateMD5Hash(string input)
        {
            // step 1, calculate MD5 hash from input
            MD5 md5 = System.Security.Cryptography.MD5.Create();
            byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(input);
            byte[] hash = md5.ComputeHash(inputBytes);

            // step 2, convert byte array to hex string
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < hash.Length; i++)
            {
                sb.Append(hash[i].ToString("X2"));
            }
            return sb.ToString();
        }
        public static string name = "Token_List";
        public static TimeSpan updatePeriod = new TimeSpan(0, 5, 0);
        public static string date = "Last_Time";

        public static RequestToken CreateRequestToken(string Email, string Password)
        {
            RequestToken token = null;
            //****Chưa chắc việc đồng bộ
            lock (HttpContext.Current.Application)
            {
                try
                {
                    Dictionary<string, TokenModel> dict = HttpContext.Current.Application[OAuthManager.name] as Dictionary<string, TokenModel>;
                    DateTime timeCheck = (DateTime)HttpContext.Current.Application[OAuthManager.date] + OAuthManager.updatePeriod;
                    //Tìm kiếm trong list các oAuth
                    DeviceDAL deviceDAL = new DeviceDAL();
                    UserDAL dal = new UserDAL();
                    if (dal.Validate(Email, Password) )//validate tài khoản
                    {
                        List<DEVICE> devices = deviceDAL.GetAllDevicesInUse(Email).ToList();
                        //              tạo token
                        DateTime date = DateTime.Now;
                        string tokenString = CalculateMD5Hash(Email + date.AddHours(2).ToString() + Password);
                        List<Device> deviceList = null;
                        if (devices.Count() > 0)
                        {
                            deviceList = new List<Device>();
                            foreach (DEVICE d in devices)
                            {
                                Device tempDevice = new Device() { Id = d.IDDEVICE, Name = d.NAME};
                                deviceList.Add(tempDevice);
                            }
                        }
                        token = new RequestToken() { Token = tokenString, Devices = deviceList, Status = REQUEST_TOKEN_STATUS.SUCCESS };
                        TokenModel tokenModel = new TokenModel() { Token = tokenString, DeviceId = -1, isAccessToken = false, Status = TokenModel.STATUS_TOKEN.SUCCESS };
                        //              thêm vào danh sách
                        dict.Add(tokenModel.Token, tokenModel);


                        //// Kiểm tra biến thời gian
                        if (date > timeCheck)
                        {
                            HttpContext.Current.Application[OAuthManager.date] = date;
                            foreach (var item in dict.Where(tkMokel => tkMokel.Value.expire <= date).ToList())
                            {
                                dict.Remove(item.Key);
                            }
                        }
                        HttpContext.Current.Application[OAuthManager.name] = dict;
                        return token;
                        // 
                    }
                    else
                    {
                        //Fail to login
                        token = new RequestToken() { Status = REQUEST_TOKEN_STATUS.FAIL, Token = "Fail to log in"};
                    }
                }
                catch (System.Exception e)
                {
                    token = new RequestToken() { Status = REQUEST_TOKEN_STATUS.FAIL, Token = e.Message };
                }
            }
            return token;
        }

        public static AccessToken CreateAccessToken(string requestToken, int IdDevice)
        {
            AccessToken token = null;
            //****Chưa chắc việc đồng bộ
            lock (HttpContext.Current.Application)
            {
                try
                {
                    Dictionary<string, TokenModel> dict = HttpContext.Current.Application[OAuthManager.name] as Dictionary<string, TokenModel>;
                    DateTime timeCheck = (DateTime)HttpContext.Current.Application[OAuthManager.date] + OAuthManager.updatePeriod;
                    //Tìm kiếm trong list các oAuth
                    DeviceDAL deviceDAL = new DeviceDAL();
                    DEVICE device = deviceDAL.GetDeviceByID(IdDevice);
                    TokenModel tokenModel = dict[requestToken];

                    if (tokenModel != null &&  device != null)//validate tài khoản
                    {
                        //              tạo token
                        DateTime date = DateTime.Now;
                        //string tokenString = CalculateMD5Hash(Email + date.AddHours(2).ToString() + Password);
                        token = new AccessToken() { Token = requestToken, Status = ACCESS_TOKEN_STATUS.SUCCESS };
                        tokenModel.DeviceId = IdDevice;
                        tokenModel.isAccessToken = true;
                        //              thêm vào danh sách

                        //// Kiểm tra biến thời gian
                        if (date > timeCheck)
                        {
                            HttpContext.Current.Application[OAuthManager.date] = date;
                            foreach (var item in dict.Where( tkMokel => tkMokel.Value.expire <= date).ToList())
                            {
                                dict.Remove(item.Key);
                            }
                        }
                        HttpContext.Current.Application[OAuthManager.name] = dict;
                        return token;
                        // 
                    }
                    else
                    {
                        //Fail to choose device
                        token = new AccessToken() { Status = ACCESS_TOKEN_STATUS.FAIL, Token = "Fail to choose device" };
                    }
                }
                catch (System.Exception e)
                {
                    token = new AccessToken() { Status = ACCESS_TOKEN_STATUS.FAIL, Token = e.Message };
                }
            }
            return token;
        }
    }
}